#include <iostream>
#include <stack>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;

const int maxn = 310;
const int inf = 1<<25;
int path[maxn];
int n, m;

struct data
{
	bool color; //blue 0, purple 1
	int rest;
	int tcolor[2];
};

struct node
{
	int to;
	int cost;
};

data da[maxn];

void print_path(int source, int target)
{
	stack<int> ans_path;
	int now = target;
	while (now != source) {
		ans_path.push(now);
		now = path[now];
	}
	cout << source + 1;
	while (!ans_path.empty()) {
		cout << " " << ans_path.top() + 1;
		ans_path.pop();
	}
}

int to_color_left(int time, int u, bool color)
{
	int duration[2] = {da[u].tcolor[0], da[u].tcolor[1]};
	if (da[u].rest > time) {
		if (da[u].color == color) return da[u].rest - duration[color];
		return da[u].rest - time;
	}
	bool color_now = !da[u].color;
	time -= da[u].rest;
	if (color_now != color) {
		if (duration[color_now] >= time) return duration[color_now] - time;
		time -= duration[color_now];
	}
	int period = duration[0] + duration[1];
	time %= period;
	if (time < duration[color]) return -time;
	return period - time;
}

int calc_color(int time, int u, int v, bool color) //blue 0 purple 1
{
	if (da[u].color == !da[v].color && da[u].rest == da[v].rest &&
			da[u].tcolor[1] == da[v].tcolor[0] &&
				da[u].tcolor[0] == da[v].tcolor[1]) return inf;
	int time_color = time;
	int u_left = to_color_left(time_color, u, color);
	int v_left = to_color_left(time_color, v, color);
	int count = 0;
	while (u_left > 0 || v_left > 0) {
		if (u_left <= 0)
			time_color += v_left;
		else if (v_left <= 0)
			time_color += u_left;
		else
			time_color += min(u_left, v_left);
		u_left = to_color_left(time_color, u, color);
		v_left = to_color_left(time_color, v, color);
		if (count++ > 4) return inf;
	}
	return time_color - time;
}

int calc(int time, int u, int v)
{
	return min(calc_color(time, u, v, false), calc_color(time, u, v, true));
}

typedef pair<int, int> p;
struct cmp
{
	bool operator()(const p & a, const p & b) { return a.second > b.second; }
};

int dijkstra(vector<vector<node> > & graph, int source, int target)
{
	int dist[n];
	fill(dist, dist + n, inf);
	priority_queue<p, vector<p>, cmp> pq;
	dist[source] = 0;
	pq.push(make_pair(source, 0));
	while (!pq.empty()) {
		p tmp = pq.top();
		pq.pop();
		int u = tmp.first;
		if (u == target) break;
		if (dist[u] < tmp.second) continue;
		for (vector<node>::iterator edge = graph[u].begin();
		 		edge != graph[u].end(); edge++) {
			int v = (*edge).to;
			int c = dist[u] + (*edge).cost;
			c += calc(dist[u], u, v);
			if (dist[v] > c) {
				path[v] = u;
				dist[v] = c;
				pq.push(make_pair(v, dist[v]));
			}
		}
	}
	if (dist[target] >= inf) return -1;
	return dist[target];
}

int main()
{
	ios::sync_with_stdio(false);
	int source, target;
	cin >> source >> target;
	cin >> n >> m;

	vector<vector<node> > graph;
	graph.resize(n);
	for (int i = 0; i < n; i++) {
		char ch;
		cin >> ch >> da[i].rest >> da[i].tcolor[0] >> da[i].tcolor[1];
		da[i].color = (ch == 'P');
	}

	for (int i = 0; i < m; i++) {
		int x, y, cost;
		cin >> x >> y >> cost;
		x--;  y--;
		node tmp;
		tmp.to = y; tmp.cost = cost;
		graph[x].push_back(tmp);
		tmp.to = x;
		graph[y].push_back(tmp);
	}

	int dis = dijkstra(graph, source-1, target-1);
	if (dis < 0)
		cout << 0 << endl;
	else {
		cout << dis << endl;
		print_path(source-1, target-1);
	}
}
